﻿using System;
using System.Diagnostics;
using System.Threading;

using WpfAdmin.Everything.Enums;

namespace WpfAdmin.Everything {
    /// <summary>
    /// Everything 服务状态查看与管理
    /// </summary>
    public static class EverythingState {
        internal static string _workPath;
        internal static bool _admin = true;
        internal static StartMode _startMode = StartMode.Service;

        /// <summary>
        /// 初始化
        /// </summary>
        public static void Init(string workPath, bool admin = true, StartMode startMode = StartMode.Service) {
            _workPath = workPath;
            _admin = admin;
            _startMode = startMode;
        }

        /// <summary>
        /// 检测 Everything 服务是否已启动
        /// </summary>
        public static bool IsStarted() {
            EverythingWrapper.PrepareEverything(_workPath);
            Version version = GetVersion();
            return version.Major > 0;
        }

        /// <summary>
        /// 启动 Everything 服务
        /// </summary>
        public static bool StartService() {
            if (!IsStarted()) {
                string option = _admin ? "-admin" : string.Empty;
                switch (_startMode) {
                    case StartMode.Install:
                        option += " -install-service";
                        break;
                    case StartMode.Service:
                        option += " -startup";
                        break;
                }
                EverythingWrapper.StartProcess(option);
                return IsStarted();
            }
            return true;
        }

        /// <summary>
        /// 检测 Everything 服务数据库是否已加载
        /// </summary>
        public static bool IsReady() {
            return EverythingWrapper.Everything_IsDBLoaded();
        }

        /// <summary>
        /// 确保 Everything 服务已启动可用
        /// </summary>
        /// <param name="intervalMs">等待间隔，单位：毫秒</param>
        /// <param name="timeoutMs">最长等待时间，单位：毫秒</param>
        /// <exception cref="InvalidOperationException">超时未检测到服务可用，则抛出异常</exception>
        public static void EnsureServiceReady(int intervalMs = 200, int timeoutMs = 60 * 1000) {
            // 确保嵌入式资源已解压并将本地 DLL 显式加载到进程，避免首次调用 DllImport 报错
            EverythingWrapper.PrepareEverything(_workPath);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            while (!IsReady() && stopwatch.ElapsedMilliseconds < timeoutMs) {
                var lastError = GetLastError();
                // TODO: log error
                Console.WriteLine(lastError.ToString());
                Thread.Sleep(intervalMs);
            }

            stopwatch.Stop();
            if (stopwatch.ElapsedMilliseconds > timeoutMs) {
                throw new InvalidOperationException("Could not start Everything process");
            } else {
                // TODO: log everything version, and cost time
                Console.WriteLine($"Everything service is ready, version: {GetVersion()}, cost time: {stopwatch.ElapsedMilliseconds}ms");
            }
        }

        /// <summary>
        /// 兼容旧签名：超时时间（秒）。建议改用 EnsureServiceReady(intervalMs, timeoutMs)。
        /// </summary>
        public static void EnsureServiceReadySeconds(int intervalMs = 200, int timeoutSeconds = 60) {
            EnsureServiceReady(intervalMs, timeoutSeconds * 1000);
        }

        /// <summary>
        /// 获取 Everything 服务当前版本号
        /// </summary>
        public static Version GetVersion() {
            uint major = EverythingWrapper.Everything_GetMajorVersion();
            uint minor = EverythingWrapper.Everything_GetMinorVersion();
            uint build = EverythingWrapper.Everything_GetBuildNumber();
            uint revision = EverythingWrapper.Everything_GetRevision();
            return new Version((int)major, (int)minor, (int)build, (int)revision);
        }

        /// <summary>
        /// 获取最后一次执行的错误码
        /// </summary>
        public static ErrorCode GetLastError() {
            return (ErrorCode)EverythingWrapper.Everything_GetLastError();
        }
    }
}
